package com.async.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.async.config.SpringBeanConfig;
import com.async.strategy.DefaultStrategy;
import com.async.strategy.StrategyService;
import com.async.strategy.context.StrategyContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 异步策略工厂
 * </p>
 * @author yang
 * @date 2024/5/17
 */
@Slf4j
public class AsyncStrategyFactory {

    public static <O extends StrategyContext, T extends StrategyService<O>> T doStrategy(String type, Class<T> clazz) {
       if (StrUtil.isEmpty(type) || clazz == null){
           return null;
       }
       Map<String, T> beanMap = SpringBeanConfig.getBeansOfType(clazz);
       if (MapUtil.isEmpty(beanMap)){
           log.error("策略类不存在，type = {},clazz = {}",type,clazz.getName());
           return null;
       }
       // 找到默认策略类
       try {
           T defaultStrategy = null;
           for (Map.Entry<String, T> entry : beanMap.entrySet()) {
               // 找到默认类型
               if (defaultStrategy == null){
                   Class<?> targetClass = AopUtils.getTargetClass(entry.getValue());
                   DefaultStrategy annotation = targetClass.getAnnotation(DefaultStrategy.class);
                   if (annotation != null){
                       defaultStrategy = entry.getValue();
                   }
               }
               // 找到匹配类型
               List<String> list = entry.getValue().listType();
               if (CollUtil.isNotEmpty(list) && list.contains(type)){
                   return entry.getValue();
               }
           }
           if (defaultStrategy != null){
               return defaultStrategy;
           }
           log.error("策略类不存在，type = {},clazz = {}",type,clazz.getName());
       }catch (Exception e){
           log.error("获取策略类失败，type = {},clazz = {}",type,clazz.getName(),e);
       }
       return null;
    }
}
